package com.ymx.darling.log;

import com.ymx.darling.log.commons.JakartaCommonsLoggingImpl;
import com.ymx.darling.log.jdk14.Jdk14LoggingImpl;
import com.ymx.darling.log.log4j2.Log4j2Impl;
import com.ymx.darling.log.nologging.NoLoggingImpl;
import com.ymx.darling.log.slf4j.Slf4jImpl;
import com.ymx.darling.log.stdout.StdOutImpl;

import java.lang.reflect.Constructor;

/**
 * @author 爱Java的小于
 */
public final class LogFactory {
    public static final String MARKER = "DARLING";
    private static Constructor<? extends Log> logConstructor;

    public static Log getLog(Class<?> clazz) {
        return getLog(clazz.getName());
    }

    public static Log getLog(String logger) {
        try {
            return logConstructor.newInstance(logger);
        } catch (Throwable var2) {
            throw new LogException(var2, "Darling为日志器'" + logger + "'创建日志实现时出错. 原因: " + var2);
        }
    }

    public static void useSlf4jLogging() {
        setImplementation(Slf4jImpl.class);
    }

    public static void useCommonsLogging() {
        setImplementation(JakartaCommonsLoggingImpl.class);
    }

    public static void useLog4J2Logging() {
        setImplementation(Log4j2Impl.class);
    }

    public static void useJdkLogging() {
        setImplementation(Jdk14LoggingImpl.class);
    }

    public static void useStdOutLogging() {
        setImplementation(StdOutImpl.class);
    }

    public static void useNoLogging() {
        setImplementation(NoLoggingImpl.class);
    }

    private static void setImplementation(Class<? extends Log> implClass) {
        try {
            Constructor<? extends Log> candidate = implClass.getConstructor(String.class);
            Log log = candidate.newInstance(LogFactory.class.getName());
            if (log.isDebugEnabled()) {
                log.debug("Darling日志初始化使用适配器:'" + implClass + "'");
            }

            logConstructor = candidate;
        } catch (Throwable throwable) {
            throw new LogException(throwable, "Darling设置日志实现时出错,原因: " + throwable);
        }
    }

    /**
     * 由框架自动配置日志实现
     */
    public static void autoConfigureLogging() {
        tryImplementation(LogFactory::useSlf4jLogging);
        tryImplementation(LogFactory::useCommonsLogging);
        tryImplementation(LogFactory::useLog4J2Logging);
        tryImplementation(LogFactory::useJdkLogging);
        tryImplementation(LogFactory::useNoLogging);
    }

    private static void tryImplementation(Runnable runnable) {
        if (logConstructor == null) {
            try {
                runnable.run();
            } catch (Throwable ignored) {}
        }
    }
}
